#include <stdio.h>
#include "crosslist_base.h"

CrossList::CrossList(void *val)
{
    value = val;
}

CrossList::~CrossList()
{
    Remove();
    //删除子链表(这段代码不能加锁!!)
    if (firstChild)
    {
        CrossList *nextChild, *currentChild = firstChild;
        do
        {
            nextChild = currentChild->next;
            delete currentChild;
            currentChild = nextChild;
        } while (currentChild);
    }
}

//当前节点和 node 的关系
bool CrossList::IsInsideOf(CrossList *node)
{
    if (!node)
        return false;
    if (prev)
    {
        CrossList *prevNode = prev;
        do {
            if (prevNode == node)
                return true;
            prevNode = prevNode->prev;
        } while(prevNode);
    }
    if (next)
    {
        CrossList *nextNode = next;
        do {
            if (nextNode == node)
                return true;
            nextNode = nextNode->next;
        } while(nextNode);
    }
    return false;
}

bool CrossList::IsChildOf(CrossList *node)
{
    if (!node)
        return false;
    return parent == node ? true : false;
}

bool CrossList::IsParentOf(CrossList *node)
{
    if (!node)
        return false;
    return node->parent == this ? true : false;
}

//添加节点,返回index,-1失败
int32_t CrossList::PushBack(CrossList *node)
{
    if (!node)
        return -1;
    node->Remove();

    Lock();

    //找到最后节点
    CrossList *tempNode = this;
    while (tempNode->next)
        tempNode = tempNode->next;
    tempNode->next = node;

    //和最后节点打好关系
    node->prev = tempNode;
    node->next = NULL;
    node->index = tempNode->index + 1;

    //和上级节点打好关系
    node->parent = tempNode->parent;
    if (node->parent)
    {
        node->parent->lastChild = node;
        node->parent->child += 1;
    }

    UnLock();
    return node->index;
}

int32_t CrossList::PushFront(CrossList *node)
{
    if (!node)
        return -1;
    node->Remove();

    Lock();

    //找到第一节点
    CrossList *tempNode = this;
    while (tempNode->prev)
        tempNode = tempNode->prev;
    tempNode->prev = node;

    //和第一节点打好关系
    node->prev = NULL;
    node->next = tempNode;
    node->index = 0;

    //和上级节点打好关系
    node->parent = tempNode->parent;
    if (node->parent)
    {
        node->parent->firstChild = node;
        node->parent->child += 1;
    }

    //往后推更新序号
    int32_t ii = node->index + 1;
    tempNode = node->next;
    while (tempNode)
    {
        tempNode->index = ii++;
        tempNode = tempNode->next;
    }

    UnLock();
    return node->index;
}

int32_t CrossList::Insert(CrossList *node, int32_t index)
{
    if (!node)
        return -1;
    node->Remove();

    Lock();
    
    CrossList *tempNode = this;
    if (index > tempNode->index)
    {
        //找到 node 的前一节点
        while (tempNode->next && index > tempNode->index)
            tempNode = tempNode->next;

        node->index = tempNode->index + 1;
        node->prev = tempNode;
        node->next = tempNode->next;
        if (node->next)
            node->next->prev = node;

        tempNode->next = node;
    }
    else
    {
        //找到 node 的后一节点
        while (tempNode->prev)
        {
            if (index == tempNode->index)
                break;
            tempNode = tempNode->prev;
        }

        node->index = tempNode->index;
        node->prev = tempNode->prev;
        node->next = tempNode;
        if (node->prev)
            node->prev->next = node;

        tempNode->prev = node;
    }

    node->parent = tempNode->parent;
    if (node->parent)
    {
        if (node->prev == NULL)
            node->parent->firstChild = node;
        else if (node->next == NULL)
            node->parent->lastChild = node;
        node->parent->child += 1;
    }

    //往后推更新序号
    int32_t ii = node->index + 1;
    tempNode = node->next;
    while (tempNode)
    {
        tempNode->index = ii++;
        tempNode = tempNode->next;
    }

    UnLock();
    return node->index;
}

int32_t CrossList::PushBackChild(CrossList *node)
{
    if (!node)
        return -1;
    node->Remove();

    Lock();

    node->next = NULL;

    if (lastChild)
    {
        node->prev = lastChild;
        lastChild->next = node;
        lastChild = node;
    }
    else
    {
        node->prev = NULL;
        firstChild = node;
        lastChild = node;
    }

    node->parent = this;
    node->index = child++;

    UnLock();
    return node->index;
}

int32_t CrossList::PushFrontChild(CrossList *node)
{
    if (!node)
        return -1;
    node->Remove();

    Lock();

    node->prev = NULL;

    if (firstChild)
    {
        node->next = firstChild;
        firstChild->prev = node;
        firstChild = node;
    }
    else
    {
        node->next = NULL;
        firstChild = node;
        lastChild = node;
    }

    node->parent = this;
    node->index = 0;
    child += 1;

    //往后推更新序号
    int32_t ii = node->index + 1;
    CrossList *tempNode = node->next;
    while (tempNode)
    {
        tempNode->index = ii++;
        tempNode = tempNode->next;
    }

    UnLock();
    return node->index;
}

int32_t CrossList::InsertChild(CrossList *node, int32_t index)
{
    if (!node)
        return -1;
    node->Remove();

    Lock();
    
    CrossList *tempNode = firstChild;
    if (!tempNode)
    {
        //第一个子代
        node->prev = NULL;
        node->next = NULL;
        node->index = 0;
    }
    else if (index < 1)
    {
        //安插到最前面
        node->prev = NULL;
        node->next = firstChild;
        node->index = 0;
        firstChild->prev = node;
    }
    else
    {
        //找到 node 的前一节点
        while (tempNode->next && index > tempNode->index)
            tempNode = tempNode->next;

        node->index = tempNode->index + 1;
        node->prev = tempNode;
        node->next = tempNode->next;
        if (node->next)
            node->next->prev = node;

        tempNode->next = node;
    }

    node->parent = this;
    if (node->prev == NULL)
        firstChild = node;
    if (node->next == NULL)
        lastChild = node;
    child += 1;

    //往后推更新序号
    int32_t ii = node->index + 1;
    tempNode = node->next;
    while (tempNode)
    {
        tempNode->index = ii++;
        tempNode = tempNode->next;
    }

    UnLock();
    return node->index;
}

//弹出节点
CrossList* CrossList::PopBackChild()
{
    CrossList* ret = NULL;
    Lock();
    ret = lastChild;
    if (ret)
        ret->Remove();
    UnLock();
    return ret;
}

CrossList* CrossList::PopFrontChild()
{
    CrossList* ret = NULL;
    Lock();
    ret = firstChild;
    if (ret)
        ret->Remove();
    UnLock();
    return ret;
}

//从链表中移除自己(保留child)
void CrossList::Remove()
{
    Lock();

    //上级关系断开
    if (parent)
    {
        if (parent->firstChild == this)
            parent->firstChild = next;
        if (parent->lastChild == this)
            parent->lastChild = prev;
        parent->child -= 1;
        parent = NULL;
    }

    //左右关系断开
    if (prev)
        prev->next = next;
    if (next)
    {
        CrossList *nextNode = next;
        nextNode->prev = prev;
        do
        {
            nextNode->index -= 1;
            nextNode = nextNode->next;
        } while(nextNode);
    }

    UnLock();
}

//查找
CrossList* CrossList::Parent()
{
    return parent;
}

CrossList* CrossList::Prev()
{
    return prev;
}

CrossList* CrossList::Next()
{
    return next;
}

CrossList* CrossList::FirstChild()
{
    return firstChild;
}

CrossList* CrossList::LastChild()
{
    return lastChild;
}

CrossList* CrossList::At(int32_t index)
{
    CrossList* tempNode = this;
    if (index < tempNode->index)
    {
        do {
            tempNode = tempNode->prev;
        } while (tempNode && tempNode->index != index);
    }
    else if (index > tempNode->index)
    {
        do {
            tempNode = tempNode->next;
        } while (tempNode && tempNode->index != index);
    }
    return tempNode;
}

CrossList* CrossList::ChildAt(int32_t index)
{
    CrossList* tempNode = firstChild;
    while (tempNode && tempNode->index != index)
        tempNode = tempNode->next;
    return tempNode;
}

//基本信息
int32_t CrossList::Index()
{
    return index;
}

int32_t CrossList::Child()
{
    return child;
}

//互斥锁
void CrossList::Lock()
{
    ;
}

void CrossList::UnLock()
{
    ;
}
